package com.topcent.tioxyc.consumer;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.rabbitmq.client.Channel;
import com.topcent.tioxyc.constants.KeyConstant;
import com.topcent.tioxyc.pojo.Assignee;
import com.topcent.tioxyc.pojo.PaymentTrackingEntity;
import com.topcent.tioxyc.pojo.SalesOrder;
import com.topcent.tioxyc.pojo.vo.CustomerPayVO;
import com.topcent.tioxyc.pojo.vo.DepartmentVO;
import com.topcent.tioxyc.pojo.vo.Lin;
import com.topcent.tioxyc.util.ApiClient;
import com.topcent.tioxyc.util.ConnmeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * @author: 陈百万
 * @date: 2025/11/12 14:28
 * @Description: 简道云销售订单完成
 */
@Component
@RabbitListener(queues = "SalesReceiptTracking")
@Slf4j
public class SalesReceiptTrackingConsumer {
    // ========== 新增：缓存配置（高频数据缓存） ==========
    // 人员信息缓存（6小时过期）
    private final LoadingCache<String, Map<String, String>> userNameCache = Caffeine.newBuilder()
            .expireAfterWrite(6, TimeUnit.HOURS)
            .build(key -> loadUserNameMap());

    // 部门信息缓存（6小时过期）
    private final LoadingCache<String, Map<String, Integer>> deptMapCache = Caffeine.newBuilder()
            .expireAfterWrite(6, TimeUnit.HOURS)
            .build(key -> loadDeptMap());

    // 客户主数据缓存（6小时过期）
    private final LoadingCache<String, Map<String, List<CustomerPayVO>>> customerCache = Caffeine.newBuilder()
            .expireAfterWrite(6, TimeUnit.HOURS)
            .build(key -> getCustomerListFromApi());

    @Lazy
    @Autowired
    private ThreadPoolTaskExecutor businessExecutor;

    private static final String DATA_CREATE = "data_create";
    private static final String DATA_UPDATE = "data_update";

    @RabbitHandler
    public void handleMessage(String msg, Channel channel, Message message) throws IOException {
        try {
            // 异步操作
            businessExecutor.submit(() -> {
                try {
                    processSalesOrder(msg); // 处理逻辑
                } catch (Exception e) {
                    log.error("异步处理简道云推送失败，payload:{}", msg, e);
                }
            });

            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            System.out.println("Message acknowledged");
        } catch (Exception e) {
            // 处理异常并拒绝消息
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            System.err.println("发送消息失败，重试中 " + e.getMessage());
        }
    }

    // ========== 处理逻辑 ==========
    private void processSalesOrder(String payload) {
        JSONObject payloadJSON = JSONUtil.parseObj(payload);
        String op = payloadJSON.getStr("op");
        String data = payloadJSON.getStr("data");
        if (DATA_UPDATE.equals(op)) {
            changeSalesOrder(data);
        }
    }

    private void changeSalesOrder(String data) {
        PaymentTrackingEntity resultEntity = new PaymentTrackingEntity();
        SalesOrder salesOrder = JSONUtil.toBean(data, SalesOrder.class);
        //2表示流程手动结束；1表示流程已完成；0表示流程进行中
        if (salesOrder.getFlowState() == 1) {
            // 从缓存获取高频数据
            Map<String, String> userNameMap = userNameCache.get("USER_MAP"); // 人员信息
            Map<String, Integer> deptMap = deptMapCache.get("DEPT_MAP"); // 部门信息
            Map<String, List<CustomerPayVO>> customerList = customerCache.get("CUSTOMER_LIST"); // 客户信息
            Header[] headers = ConnmeUtils.createHeaders();
            String orderNo = salesOrder.get_widget_1718759603973(); // 销售订单号
            resultEntity.set_widget_1759203125362(orderNo);
            Double hl = salesOrder.get_widget_1718759603987(); // 汇率
            resultEntity.set_widget_1760327721440(orderNo); // 唯一码

            String pzhb = salesOrder.get_widget_1718759603985(); // 凭证货币
            resultEntity.set_widget_1759203125364(pzhb);

            String ywy = salesOrder.get_widget_1718759603990(); // 业务员
            if(ObjectUtils.isNotEmpty(ywy)){
                ywy = JSONUtil.parseObj(ywy).getStr("username");
            }
            resultEntity.set_widget_1759202420876(ywy);

            // 销售组织【部门】
            Integer xszz = ObjectUtils.isNotEmpty(salesOrder.get_widget_1718759603978()) ? Integer.parseInt(JSONUtil.parseObj(salesOrder.get_widget_1718759603978()).getStr("dept_no")) : null;
            resultEntity.set_widget_1759202420875(xszz);

            String customer = salesOrder.get_widget_1718759603979(); // 客户
            String customerCode; // 客户编码
            String customerShortName = ""; // 客户简称
            //拆分逻辑：非空且包含「;」才拆分
            if (customer != null && !customer.trim().isEmpty() && customer.contains(";")) {
                // 按「;」分割，最多分割成2部分（避免字符串中有多个;导致后续元素干扰）
                String[] customerParts = customer.split(";", 2);

                // 赋值客户编码（第一部分，去空格）
                if (customerParts.length > 0 && !customerParts[0].trim().isEmpty()) {
                    customerCode = customerParts[0].trim();
                } else {
                    customerCode = "";
                }

                // 赋值客户简称（第二部分，去空格）
                if (customerParts.length > 1 && !customerParts[1].trim().isEmpty()) {
                    customerShortName = customerParts[1].trim();
                }
            } else {
                // 不满足拆分条件：原始值非空则赋值给客户编码，简称留空；原始值为空则两者都留空
                if (customer != null && !customer.trim().isEmpty()) {
                    customerCode = customer.trim();
                } else {
                    customerCode = "";
                }
            }
            resultEntity.set_widget_1759203125359(customerCode);
            resultEntity.set_widget_1759203125360(customerShortName);

            // 跟进人匹配
            Map<String, String> deptPersonMap = new HashMap<>();
            deptPersonMap.put("DIY销售部", "陈丽娜");
            deptPersonMap.put("ECO贸易销售部", "陈丽娜");
            deptPersonMap.put("ECO应用销售部", "张艳清");
            deptPersonMap.put("OBM销售部", "张艳清");
            deptPersonMap.put("PRO欧美销售部", "张艳清");
            deptPersonMap.put("PRO亚非销售部", "张艳清");
            deptPersonMap.put("BCP东南亚销售部", "陈丽娜");
            deptPersonMap.put("BCP美澳销售部", "陈丽娜");
            deptPersonMap.put("BCP欧亚销售部", "陈丽娜");
            deptPersonMap.put("BCP中非销售部", "张艳清");
            String deptName = ObjectUtils.isNotEmpty(salesOrder.get_widget_1718759603978()) ? JSONUtil.parseObj(salesOrder.get_widget_1718759603978()).getStr("name") : "";
            String personCharge = deptPersonMap.getOrDefault(deptName, "待分配");
            String s = userNameMap.get(personCharge); // 负责人

            resultEntity.set_widget_1760423176427(s);

            // 客户信息匹配（保持不变）
            CustomerPayVO customerPayVO = Optional.ofNullable(customerList)
                    .map(map -> map.get(customerCode))
                    .filter(list -> !list.isEmpty())
                    .map(List::getFirst)
                    .orElse(null);

            // 3. 客户相关字段（保持不变）
            int dayNum = 0;
            if (customerPayVO != null) {
                resultEntity.set_widget_1759203125367(customerPayVO.get_widget_1723200599102());
                resultEntity.set_widget_1760423989808(customerPayVO.get_widget_1723200599103());
                resultEntity.set_widget_1759203125369(customerPayVO.get_widget_1760518728455()); // 结算天数
                // 避免空指针：如果客户付款天数字段为null，dayNum设为0
                if (resultEntity.get_widget_1759203125369() != null) {
                    dayNum = Integer.parseInt(resultEntity.get_widget_1759203125369());
                }
            }
            // 判断之前销售订单是否存在，不存在添加，存在修改
            List<Lin> xsLinList = getSkdId(orderNo,"669cb709a73cc1289c49800e","68db4c7420407efb3e3bc238","_widget_1759203125362");
            if (xsLinList.isEmpty()) {
                log.info("未找到销售单号{}对应的销售单ID", orderNo);
                // 添加
                Map<String, Object> parameterFix = new HashMap<>();
                parameterFix.put("app_id", "669cb709a73cc1289c49800e");
                parameterFix.put("entry_id", "68db4c7420407efb3e3bc238");
                parameterFix.put("data", ConnmeUtils.convertEntityToMap(resultEntity));
                resultEntity.set_id(null);
                String jsonSale = JSONUtil.toJsonStr(parameterFix);
                ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/create", headers, jsonSale);
            }else {
                // 修改
                String xsId = xsLinList.getLast().get_id();
                resultEntity.set_id(xsId);
                Map<String, Object> parameterInster = new HashMap<>();
                parameterInster.put("app_id", "669cb709a73cc1289c49800e");
                parameterInster.put("entry_id", "68db4c7420407efb3e3bc238");
                parameterInster.put("is_start_trigger", "true");
                parameterInster.put("data_id", resultEntity.get_id());
                resultEntity.set_id(null);
                parameterInster.put("data", ConnmeUtils.convertEntityToMapNull(resultEntity));
                String jsonSalee = JSONUtil.toJsonStr(parameterInster);
                ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/update", headers, jsonSalee);
            }
            // 以上逻辑-流程状态为已完成
        }
    }

    // ========== 新增：缓存加载方法（原有高频查询逻辑迁移至此） ==========
    /** 加载人员信息到缓存 */
    private Map<String, String> loadUserNameMap() {
        log.info("加载人员信息到缓存");
        Header[] headers = ConnmeUtils.createHeaders();
        Map<String, Object> person = new HashMap<>();
        person.put("dept_no", 1);
        person.put("has_child", true);
        JSONObject personResult = ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/corp/department/user/list", headers, JSONUtil.toJsonStr(person));
        String personData = personResult.getStr("users");
        JSONArray personObjects = JSONUtil.parseArray(personData);
        List<Assignee> personList = JSONUtil.toList(personObjects, Assignee.class);
        return personList.stream()
                .collect(Collectors.toMap(Assignee::getName, Assignee::getUsername, (v1, v2) -> v1));
    }

    /** 加载部门信息到缓存 */
    private Map<String, Integer> loadDeptMap() {
        log.info("加载部门信息到缓存");
        Header[] headers = ConnmeUtils.createHeaders();
        Map<String, Object> cond = new HashMap<>();
        cond.put("dept_no", 1);
        cond.put("has_child", true);
        JSONObject deptResult = ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/corp/department/list", headers, JSONUtil.toJsonStr(cond));
        String deptData = deptResult.getStr("departments");
        JSONArray objects = JSONUtil.parseArray(deptData);
        List<DepartmentVO> deptList = JSONUtil.toList(objects, DepartmentVO.class);
        return deptList.stream()
                .collect(Collectors.toMap(DepartmentVO::getName, DepartmentVO::getDept_no, (v1, v2) -> v1));
    }

    /** 加载客户主数据到缓存（原有getCustomerList逻辑迁移） */
    private Map<String, List<CustomerPayVO>> getCustomerListFromApi() {
        log.info("加载客户主数据到缓存");
        List<CustomerPayVO> customerList = new ArrayList<>();
        Header[] headers = ConnmeUtils.createHeaders();
        Map<String, Object> parameter = new HashMap<>();
        parameter.put("app_id", "66a6f42ff97af74b02d217df");
        parameter.put("entry_id", "66a6f443333584e2c128154f");
        boolean fale = true;
        String zh = "";
        do {
            if (!zh.isEmpty()) {
                parameter.put("data_id", zh);
            }
            parameter.put("limit", 100);
            String jsonSale = JSONUtil.toJsonStr(parameter);
            JSONObject jdySale = ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/list", headers, jsonSale);
            String data = jdySale.getStr("data");
            JSONArray objects = JSONUtil.parseArray(data);
            List<CustomerPayVO> list = JSONUtil.toList(objects, CustomerPayVO.class);
            if (list.size() == 100) {
                zh = list.getLast().get_id();
            } else {
                fale = false;
            }
            customerList.addAll(list);
        } while (fale);
        return customerList.stream()
                .collect(Collectors.groupingBy(customer -> customer.get_widget_1722305048887().trim()));
    }

    public List<Lin> getSkdId(String skNo, String appId, String entryId, String txt) {
        List<Lin> linList = new ArrayList<>();
        Header[] headers = ConnmeUtils.createHeaders();
        Map<String, Object> parameter = new HashMap<>();
        parameter.put("app_id", appId);
        parameter.put("entry_id", entryId);
        Map<String, Object> filter = new HashMap<>();
        filter.put("rel", "and");
        Map<String, Object> cond = new HashMap<>();
        cond.put("field", txt);
        cond.put("type", "text");
        cond.put("method", "eq");
        List<String> values = new ArrayList<>();
        values.add(skNo);
        cond.put("value", values);
        List<Map<String, Object>> conds = new ArrayList<>();
        conds.add(cond);
        filter.put("cond", conds);
        parameter.put("filter", filter);
        boolean fale = true;
        String zh = "";
        do {
            if (!zh.isEmpty()) {
                parameter.put("data_id", zh);
            }
            parameter.put("limit", 100);
            String jsonSale = JSONUtil.toJsonStr(parameter);
            JSONObject jdySale = ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/list", headers, jsonSale);
            String data = jdySale.getStr("data");
            JSONArray objects = JSONUtil.parseArray(data);
            List<Lin> list = JSONUtil.toList(objects, Lin.class);
            if (list.size() == 100) {
                zh = list.getLast().get_id();
            } else {
                fale = false;
            }
            linList.addAll(list);
        } while (fale);
        return linList;
    }


}
